<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>async 函数</title>
	</head>
	<body>
		<p>ES2017 标准引入了 async 函数，使得异步操作变得更加方便。async 函数是什么？一句话，它就是 Generator 函数的语法糖。</p>
		<p>async函数对 Generator 函数的改进，体现在以下四点：</p>
		<p>（1）内置执行器。Generator 函数的执行必须靠执行器，所以才有了co模块，而async函数自带执行器。也就是说，async函数的执行，与普通函数一模一样，只要一行。</p>
		<p>（2）更好的语义。async和await，比起星号和yield，语义更清楚了。async表示函数里有异步操作，await表示紧跟在后面的表达式需要等待结果。</p>
		<p>（3）更广的适用性。co模块约定，yield命令后面只能是 Thunk 函数或 Promise 对象，而async函数的await命令后面，可以是 Promise
			对象和原始类型的值（数值、字符串和布尔值，但这时会自动转成立即 resolved 的 Promise 对象）。</p>
		<p>（4）返回值是 Promise。async函数的返回值是 Promise 对象，这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then方法指定下一步的操作。</p>
		<p>进一步说，async函数完全可以看作多个异步操作，包装成的一个 Promise 对象，而await命令就是内部then命令的语法糖。</p>
		<script type="text/javascript">
			function print(s) {
				console.log(s);
				return s + "-printed"
			}

			const gen1 = function*() {
				const f1 = yield print("hello");
				const f2 = yield print("world");
				console.log(f1);
				console.log(f2);
			};
			let gen = gen1();
			gen.next(); // "hello" 
			gen.next(); // "world"
			gen.next(); // undefined undefined
			// 同上
			// 比较就会发现，async函数就是将 Generator 函数的星号（*）替换成async，将yield替换成await，仅此而已
			const gen2 = async function() {
				const f1 = await print("hello");
				const f2 = await print("world");
				console.log(f1);
				console.log(f2);
			};
			gen2(); // "hello" "world" "hello-printed" "world-printed"
		</script>
	</body>
</html>
